package com.xbongbong.pro.statistic.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.bi.ChartSourceEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.domain.entity.ChartCategoryEntity;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.domain.entity.IndexSetEntity;
import com.xbongbong.pro.enums.BoardTypeEnum;
import com.xbongbong.pro.enums.errorcodes.StatisticsServicesErrorCodeEnum;
import com.xbongbong.pro.index.pojo.IndexBoardChartSavePojo;
import com.xbongbong.pro.index.pojo.IndexSetDataPojo;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.pro.statistic.constant.ChartInitConstant;
import com.xbongbong.pro.statistic.enums.ChartCategoryAliasEnum;
import com.xbongbong.pro.statistic.enums.ChartCategoryTypeEnum;
import com.xbongbong.pro.statistic.enums.ChartTypeEnum;
import com.xbongbong.pro.statistic.enums.StatisticsTypeEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.model.ChartCategoryModel;
import com.xbongbong.pro.statistic.model.ChartCustomModel;
import com.xbongbong.pro.statistic.model.ChartModel;
import com.xbongbong.pro.statistic.pojo.dto.ChartCategoryInitDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartCategoryParentChildDTO;
import com.xbongbong.pro.statistic.pojo.dto.ChartInitDTO;
import com.xbongbong.pro.statistic.pojo.vo.ChartCategoryInitVO;
import com.xbongbong.pro.statistic.pojo.vo.ChartInitVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.MirrorModuleEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.model.IndexSetModel;
import com.xbongbong.sys.domain.entity.MirrorCompanyEntity;
import com.xbongbong.sys.domain.entity.MirrorInfoEntity;
import com.xbongbong.sys.model.MirrorCompanyModel;
import com.xbongbong.sys.model.MirrorInfoModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 图表初始化相关方法
 *
 * @author 徐俊杰
 * @version v1.0
 * @date 2019/4/3 10:39
 * @since v1.0
 */
@Component
public class ChartInitHelp {
    private static final Logger LOG = LoggerFactory.getLogger(ChartInitHelp.class);
    @Resource
    private ChartCategoryModel chartCategoryModel;
    @Resource
    private ChartModel chartModel;
    @Resource
    private ChartCustomModel chartCustomModel;
    @Resource
    private CustomHelp customHelp;
    @Resource
    private IndexSetModel indexSetModel;
    @Resource
    private MirrorCompanyModel mirrorCompanyModel;
    @Resource
    private MirrorInfoModel mirrorInfoModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private IndexInitHelp indexInitHelp;

    /**
     * 获取首页图表数据
     *
     * @param chartCategoryInitDTO
     * @throws
     * @return
     * @author hongxiao
     * @date 2021-01-29 15:55
     * @since
     * @version
     * @update by zcp 2021年10月26日19:37:53 更改入参，并使方法支持查询特定分类、图表
     */
    public ChartCategoryInitVO getIndexChartCategory(ChartCategoryInitDTO chartCategoryInitDTO) throws XbbException {
        String corpid = chartCategoryInitDTO.getCorpid();
        Set<Long> systemChartIdSet = chartCategoryInitDTO.getSystemChartIdSet();
        Set<Long> customChartIdSet = chartCategoryInitDTO.getCustomChartIdSet();
        ChartCategoryInitVO chartCategoryInitVO = new ChartCategoryInitVO();
        //查询公司图表分类
        Map<String, Object> categoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        categoryMap.put(StringConstant.CORPID, corpid);
        //未删除
        categoryMap.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        //开启的状态
        categoryMap.put("enable", BasicConstant.IS_USE);
        //首页所需图表类型
        List<Integer> typeInHome = ChartCategoryTypeEnum.getCodeList4Home();
        categoryMap.put("typeIn", typeInHome);
        List<ChartCategoryEntity> allCategoryList = chartCategoryModel.findEntitys(categoryMap);
        chartCategoryInitVO.setCategoryList(allCategoryList);
        //获取公司图表
        Map<String, Object> chartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        chartMap.put(StringConstant.CORPID, corpid);
        //未删除
        chartMap.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        chartMap.put(StringConstant.COLUMNS, "id,corpid,category,statistics_type,system_code,enable,chart_type,show_types,publish,name,old_name,name_en,icon,color,permissions,driver_sources,ref_types,unit,sort,explains,join_rule,remove_rule,scope_rule,power_type,item_style_option,chart_classify,num_format,single");
        //是否开启
        chartMap.put("enable", BasicConstant.IS_USE);
        //TODO 此处先做判空处理，因为有些方法此次无法改造，导致某些场景下这个参数为空，只有等宏晓和
        if (CollectionsUtil.isNotEmpty(systemChartIdSet)) {
            chartMap.put("idIn", systemChartIdSet);
        }
        List<ChartEntity> allChartList = chartModel.findEntitys(chartMap);
        if (CollectionsUtil.isNotEmpty(customChartIdSet)) {
            chartMap.put("idIn", customChartIdSet);
        }
        allChartList.addAll(chartCustomModel.findEntitys(chartMap));
        for (ChartEntity chartEntity : allChartList) {
            String unit = customHelp.setUnit(chartEntity);
            chartEntity.setUnit(unit);
        }
        chartCategoryInitVO.setChartList(allChartList);

        return chartCategoryInitVO;
    }

    /**
     * 报表分类初始化
     *
     * @param chartCategoryInitDTO 入参
     * @return com.xbongbong.pro.statistic.pojo.vo.ChartCategoryInitVO
     * @throws XbbException 父类异常
     * @author 徐俊杰
     * @date 2019/1/23 15:23
     */
    public ChartCategoryInitVO chartCategoryInit(ChartCategoryInitDTO chartCategoryInitDTO) throws XbbException {
        ChartCategoryInitVO chartCategoryInitVO = new ChartCategoryInitVO();
        String corpid = chartCategoryInitDTO.getCorpid();
        //web首页左、右侧，图表中心系统
        List<Integer> typeIn = ChartCategoryTypeEnum.getCodeList4Init();
        //本公司的系统报表分类List
        Map<String, Object> chartCategoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        chartCategoryMap.put("corpid", corpid);
        chartCategoryMap.put("typeIn", typeIn);
        chartCategoryMap.put("orderByStr", "add_time DESC");
        List<ChartCategoryEntity> systemChartCategoryList = chartCategoryModel.findEntitys(chartCategoryMap);
        //默认的报表分类List（corpid = 0）
        chartCategoryMap.put("corpid", "0");
        List<ChartCategoryEntity> defaultChartCategoryList = chartCategoryModel.findEntitys(chartCategoryMap);

        // 根据alias判断是否插入数据
        ChartCategoryParentChildDTO chartCategoryParentChildDTO = packageChartCategoryParentChildDTO(systemChartCategoryList, defaultChartCategoryList);
        List<String> insertParentAliasList = getInsertAlias(chartCategoryParentChildDTO.getDefaultParentChartCategoryList(), chartCategoryParentChildDTO.getSystemParentChartCategoryList());
        List<String> insertChildAliasList = getInsertAlias(chartCategoryParentChildDTO.getDefaultChildChartCategoryList(), chartCategoryParentChildDTO.getSystemChildChartCategoryList());
        if (CollectionsUtil.isEmpty(insertParentAliasList) && CollectionsUtil.isEmpty(insertChildAliasList)) {
            //不需要初始化
            chartCategoryInitVO.setFlag(ChartInitConstant.CATEGORY_INIT_NO_NEED);
        } else {
            //加一个缓存标志锁
            String flag = paasRedisHelper.getValue(RedisPrefixConstant.CHART_CATEGORY_INIT, corpid);
            if (Objects.equals(flag, null)) {
                paasRedisHelper.setValue(RedisPrefixConstant.CHART_CATEGORY_INIT, corpid, "1", RedisConstant.TINY_DURATION);
            } else {
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224033, StatisticsServicesErrorCodeEnum.API_ERROR_224033.getMsg());
            }
            // 插入父分类
            if (CollectionsUtil.isNotEmpty(insertParentAliasList)) {
                List<ChartCategoryEntity> insertParentList = insertParentChartCategory(corpid, chartCategoryParentChildDTO.getDefaultParentChartCategoryList(), insertParentAliasList);
                if (CollectionsUtil.isNotEmpty(insertParentList)) {
                    chartCategoryParentChildDTO.getSystemParentChartCategoryList().addAll(insertParentList);
                }
            }
            // 插入子分类
            if (CollectionsUtil.isNotEmpty(insertChildAliasList)) {
                Map<Long, Long> parentIdMap = getCategoryIdMap(chartCategoryParentChildDTO.getDefaultParentChartCategoryList(), chartCategoryParentChildDTO.getSystemParentChartCategoryList());
                insertChildChartCategory(corpid, chartCategoryParentChildDTO.getDefaultChildChartCategoryList(), insertChildAliasList, parentIdMap);
            }

            chartCategoryInitVO.setFlag(ChartInitConstant.CATEGORY_INIT_SUCCESS);
            paasRedisHelper.removeValue(RedisPrefixConstant.CHART_CATEGORY_INIT, corpid);
        }

        return chartCategoryInitVO;
    }

    /**
     * 图表初始化
     *
     * @param chartInitDTO 入参（包含corpid）
     * @return com.xbongbong.pro.statistic.pojo.vo.ChartInitVO
     * @throws XbbException 父类异常
     * @author 徐俊杰
     * @date 2019/1/31 15:05
     * @since v1.0
     */
    public ChartInitVO chartInit(ChartInitDTO chartInitDTO) throws XbbException {
        //获取系统图表
        Map<String, Object> chartInitMap = new HashMap<>(16);
        String corpid = chartInitDTO.getCorpid();
        ChartInitVO chartInitVO = new ChartInitVO();
        chartInitMap.put("corpid", corpid);
        chartInitMap.put("statisticsType", StatisticsTypeEnum.SYSTEM_STATISTIC.getCode());
        chartInitMap.put("orderByStr", "add_time DESC");
        List<ChartEntity> systemChartList = chartModel.findEntitys(chartInitMap);
        //获取默认图表
        chartInitMap.put("corpid", "0");
        List<ChartEntity> defaultChartList = chartModel.findEntitys(chartInitMap);

        // 需要插入的数据
        List<ChartEntity> insertSystemCodeList = getInsertSystemCode(defaultChartList, systemChartList);
        if (CollectionsUtil.isEmpty(insertSystemCodeList)) {
            //不需要初始化
            chartInitVO.setFlag(ChartInitConstant.CHART_INIT_NO_NEED);
        } else {
            String flag = paasRedisHelper.getValue(RedisPrefixConstant.CHART_INIT, corpid);
            if (Objects.equals(flag, null)) {
                paasRedisHelper.setValue(RedisPrefixConstant.CHART_INIT, corpid, "1", RedisConstant.TINY_DURATION);
            } else {
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224033, StatisticsServicesErrorCodeEnum.API_ERROR_224033.getMsg());
            }
            //获取默认--系统图表分类Id的map
            Map<Long, Long> categoryIdMap = getOldNewCategoryIdMap(chartInitDTO);
            List<ChartEntity> newChartList = new ArrayList<>();
            for (ChartEntity oldEntity : insertSystemCodeList) {
                JSONArray newCidArr = new JSONArray();
                List<Long> oldCidArr = oldEntity.getCategory().toJavaList(Long.class);
                for (Long cid : oldCidArr) {
                    newCidArr.add(categoryIdMap.get(cid));
                }
                ChartEntity newEntity = new ChartEntity();
                BeanUtil.copyProperties(oldEntity, newEntity);
                newEntity.setId(null);
                newEntity.setCorpid(corpid);
                newEntity.setCategory(newCidArr);
                newEntity.setAddTime(DateTimeUtil.getInt());
                //新公司的“销售漏斗”的统计维度需要设置“负责人”，旧公司还是按照“创建人” 维度来
                setSalesFunnelStatisticsRule(oldEntity,newEntity);
                newChartList.add(newEntity);
            }
            chartModel.insertBatch(newChartList);

            // ----- 更新indexSet -----
            // 公司若使用镜像，则根据镜像配置关闭相应的类别
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("columns", "version_id");
            param.put("corpid", corpid);
            MirrorCompanyEntity mirrorCompany = mirrorCompanyModel.getMirrorCompany(param);
            if (Objects.nonNull(mirrorCompany)) {
                updateSimpleIndexSetChart(corpid, newChartList, mirrorCompany.getVersionId());
            } else {
                // 公司不使用镜像时按原逻辑
                updateIndexSetChart(corpid, newChartList);
            }
            //添加新的默认报表成功
            chartInitVO.setFlag(ChartInitConstant.CHART_INIT_SUCCESS);
            paasRedisHelper.removeValue(RedisPrefixConstant.CHART_INIT, corpid);
        }
        return chartInitVO;
    }

    private void setSalesFunnelStatisticsRule(ChartEntity oldEntity , ChartEntity newEntity){
        //system_code 为 301_05_01 首页-销售漏斗图表， 301_05_02 图表中心-销售漏斗图表 需要设置默认统计规则
        if(SystemCodeEnum.OPPORTUNITY_FUNNEL_HOME.getSystemCode().equals(oldEntity.getSystemCode()) || SystemCodeEnum.OPPORTUNITY_FUNNEL_CHART.getSystemCode().equals(oldEntity.getSystemCode())){
            //归属人的默认维度是"负责人"(新，老公司的时间默认统计维度都是"预计结束时间"，在展示的时候已经兼容了,所以不需要单独在设置)
            JSONObject belongObj = new JSONObject();
            belongObj.put("name","负责人");
            belongObj.put("attr", SalesOpportunityEnum.OWNER_ID.getAttr());

            newEntity.setBelongAttr(belongObj);
        }
    }

    /**
     * 初始化后获取公司的分类和图表
     *
     * @param chartInitDTO 包含corpid
     * @return com.xbongbong.pro.statistic.pojo.vo.ChartCategoryInitVO
     * @author 徐俊杰
     * @date 2019/4/3 11:26
     * @since v1.0
     */
    public ChartCategoryInitVO categoryAndChartList(ChartInitDTO chartInitDTO) throws XbbException {
        ChartCategoryInitVO chartCategoryInitVO = new ChartCategoryInitVO();
        String corpid = chartInitDTO.getCorpid();
        //查询公司图表分类
        Map<String, Object> categoryMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        categoryMap.put("corpid", corpid);
        //未删除
        categoryMap.put("del", 0);
        //开启的状态
        categoryMap.put("enable", 1);
        //首页所需图表类型
        List<Integer> typeInHome = ChartCategoryTypeEnum.getCodeList4Home();
        categoryMap.put("typeIn", typeInHome);
        List<ChartCategoryEntity> allCategoryList = chartCategoryModel.findEntitys(categoryMap);
        chartCategoryInitVO.setCategoryList(allCategoryList);
        //获取公司图表
        Map<String, Object> chartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        chartMap.put("corpid", corpid);
        //未删除
        chartMap.put("del", 0);
        //是否开启
        chartMap.put("enable", 1);
        List<ChartEntity> allChartList = chartModel.findEntitys(chartMap);
        allChartList.addAll(chartCustomModel.findEntitys(chartMap));
        for (ChartEntity chartEntity : allChartList) {
            String unit = customHelp.setUnit(chartEntity);
            chartEntity.setUnit(unit);
        }
        chartCategoryInitVO.setChartList(allChartList);
        // 初始化首页看板
        indexInitHelp.initConfig(corpid, allCategoryList, allChartList);
        return chartCategoryInitVO;
    }

    /**
     * 包装chartCategoryParentChildDTO
     *
     * @param systemChartCategoryList  公司系统报表分类列表
     * @param defaultChartCategoryList 默认报表分类列表
     * @return com.xbongbong.pro.statistic.pojo.dto.ChartCategoryParentChildDTO
     * @author 徐俊杰
     * @date 2019/1/29 18:50
     * @since v1.0
     */
    private ChartCategoryParentChildDTO packageChartCategoryParentChildDTO(List<ChartCategoryEntity> systemChartCategoryList, List<ChartCategoryEntity> defaultChartCategoryList) {
        Map<String, List<ChartCategoryEntity>> defaultChartCategoryListMap = separateParentChildList(defaultChartCategoryList);
        Map<String, List<ChartCategoryEntity>> systemChartCategoryListMap = separateParentChildList(systemChartCategoryList);
        //拆成默认父分类，默认子分类，系统父分类，系统子分类
        List<ChartCategoryEntity> defaultParentChartCategoryList = defaultChartCategoryListMap.get("parent");
        List<ChartCategoryEntity> defaultChildChartCategoryList = defaultChartCategoryListMap.get("child");
        List<ChartCategoryEntity> systemChildChartCategoryList = systemChartCategoryListMap.get("child");
        List<ChartCategoryEntity> systemParentChartCategoryList = systemChartCategoryListMap.get("parent");
        Integer defaultParentChartCategoryCount = defaultParentChartCategoryList.size();
        Integer defaultChildChartCategoryCount = defaultChildChartCategoryList.size();
        Integer systemParentChartCategoryCount = systemParentChartCategoryList.size();
        Integer systemChildChartCategoryCount = systemChildChartCategoryList.size();
        ChartCategoryParentChildDTO chartCategoryParentChildDTO = new ChartCategoryParentChildDTO();
        //List
        chartCategoryParentChildDTO.setDefaultParentChartCategoryList(defaultParentChartCategoryList);
        chartCategoryParentChildDTO.setDefaultChildChartCategoryList(defaultChildChartCategoryList);
        chartCategoryParentChildDTO.setSystemParentChartCategoryList(systemParentChartCategoryList);
        chartCategoryParentChildDTO.setSystemChildChartCategoryList(systemChildChartCategoryList);
        //Count
        chartCategoryParentChildDTO.setDefaultParentChartCategoryCount(defaultParentChartCategoryCount);
        chartCategoryParentChildDTO.setDefaultChildChartCategoryCount(defaultChildChartCategoryCount);
        chartCategoryParentChildDTO.setSystemParentChartCategoryCount(systemParentChartCategoryCount);
        chartCategoryParentChildDTO.setSystemChildChartCategoryCount(systemChildChartCategoryCount);
        return chartCategoryParentChildDTO;
    }

    /**
     * 从报表分类总列表中区分出父子分类列表
     *
     * @param chartCategoryList 报表分类列表（不区分父子分类）
     * @return java.util.Map<java.lang.String   ,   java.util.List   <   com.xbongbong.pro.domain.entity.ChartCategoryEntity>>
     * @author 徐俊杰
     * @date 2019/1/29 19:33
     * @since v1.0
     */
    private Map<String, List<ChartCategoryEntity>> separateParentChildList(List<ChartCategoryEntity> chartCategoryList) {
        List<ChartCategoryEntity> parentChartCategoryList = new ArrayList<>();
        List<ChartCategoryEntity> childChartCategoryList = new ArrayList<>();
        Map<String, List<ChartCategoryEntity>> chartCategoryListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ChartCategoryEntity entity : chartCategoryList) {
            if (ChartInitConstant.ROOT_PARENT_CATEGORY_ID == entity.getParentId()) {
                parentChartCategoryList.add(entity);
            } else {
                childChartCategoryList.add(entity);
            }
        }
        chartCategoryListMap.put("parent", parentChartCategoryList);
        chartCategoryListMap.put("child", childChartCategoryList);
        return chartCategoryListMap;
    }


    /**
     * 父分类数量相等，子分类数量不相等，插入新增子分类
     *
     * @param chartCategoryParentChildDTO 父子分类相关参数
     * @param chartCategoryInitDTO        获取corpid
     * @author 徐俊杰
     * @date 2019/1/29 15:56
     * @since v1.0
     */
    private void insertNewChildChartCategory(ChartCategoryParentChildDTO chartCategoryParentChildDTO, ChartCategoryInitDTO chartCategoryInitDTO) {
        //默认子分类数量（corpid = 0）
        Integer defaultChildChartCategoryCount = chartCategoryParentChildDTO.getDefaultChildChartCategoryCount();
        //系统子分类数量
        Integer systemChildChartCategoryCount = chartCategoryParentChildDTO.getSystemChildChartCategoryCount();
        //默认父分类列表
        List<ChartCategoryEntity> defaultParentChartCategoryList = chartCategoryParentChildDTO.getDefaultParentChartCategoryList();
        //默认子分类列表
        List<ChartCategoryEntity> defaultChildChartCategoryList = chartCategoryParentChildDTO.getDefaultChildChartCategoryList();
        //系统父分类列表
        List<ChartCategoryEntity> systemParentChartCategoryList = chartCategoryParentChildDTO.getSystemParentChartCategoryList();
        //获取默认分类--系统分类的父IdMap
        Map<Long, Long> parentIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ChartCategoryEntity oldEntity : defaultParentChartCategoryList) {
            for (ChartCategoryEntity newEntity : systemParentChartCategoryList) {
                //根据alias建立默认分类--系统分类的父IdMap
                if (Objects.equals(oldEntity.getAlias(), newEntity.getAlias())) {
                    parentIdMap.put(oldEntity.getId(), newEntity.getId());
                }
            }
        }
        //根据默认子分类和系统分类子分类的差量批量插入子分类
        Integer difference = defaultChildChartCategoryCount - systemChildChartCategoryCount;
        List<ChartCategoryEntity> newChildChartCategoryList = new ArrayList<>();
        String corpid = chartCategoryInitDTO.getCorpid();
        //根据add_time从大到小添加子分类
        for (Integer i = 0; i < difference; i++) {
            ChartCategoryEntity oldEntity = defaultChildChartCategoryList.get(i);
            ChartCategoryEntity newEntity = new ChartCategoryEntity();
            BeanUtil.copyProperties(oldEntity, newEntity);
            newEntity.setCorpid(corpid);
            newEntity.setId(null);
            newEntity.setParentId(parentIdMap.get(newEntity.getParentId()));
            newEntity.setAddTime(DateTimeUtil.getInt());
            newChildChartCategoryList.add(newEntity);
        }
        chartCategoryModel.insertBatch(newChildChartCategoryList);
    }

    /**
     * 父分类数量不相等，子分类数量相等，插入新增父分类
     *
     * @param chartCategoryParentChildDTO 父子分类相关参数
     * @param chartCategoryInitDTO        获取corpid
     * @throws XbbException updateIndexSet会出现异常
     * @author 徐俊杰
     * @date 2019/1/29 16:04
     * @since v1.0
     */
    private void insertNewParentChartCategory(ChartCategoryParentChildDTO chartCategoryParentChildDTO, ChartCategoryInitDTO chartCategoryInitDTO) throws XbbException {
        //默认父分类数量
        Integer defaultParentChartCategoryCount = chartCategoryParentChildDTO.getDefaultParentChartCategoryCount();
        //系统父分类数量
        Integer systemParentChartCategoryCount = chartCategoryParentChildDTO.getSystemParentChartCategoryCount();
        //默认父分类列表
        List<ChartCategoryEntity> defaultParentChartCategoryList = chartCategoryParentChildDTO.getDefaultParentChartCategoryList();
        Integer difference = defaultParentChartCategoryCount - systemParentChartCategoryCount;
        String corpid = chartCategoryInitDTO.getCorpid();
        //根据add_time添加父分类列表
        List<ChartCategoryEntity> newParentChartCategoryList = new ArrayList<>();
        for (Integer i = 0; i < difference; i++) {
            ChartCategoryEntity oldEntity = defaultParentChartCategoryList.get(i);
            ChartCategoryEntity newEntity = new ChartCategoryEntity();
            BeanUtil.copyProperties(oldEntity, newEntity);
            newEntity.setId(null);
            newEntity.setCorpid(corpid);
            newEntity.setAddTime(DateTimeUtil.getInt());
            newParentChartCategoryList.add(newEntity);
        }
        chartCategoryModel.insertBatch(newParentChartCategoryList);
        // 公司若使用镜像，则根据镜像配置关闭相应的类别
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("columns", "version_id");
        param.put("corpid", corpid);
        MirrorCompanyEntity mirrorCompany = mirrorCompanyModel.getMirrorCompany(param);
        if (Objects.nonNull(mirrorCompany)) {
            updateSimpleIndexSet(corpid, newParentChartCategoryList, mirrorCompany.getVersionId());
        } else {
            // 公司不使用镜像时按原逻辑
            updateIndexSet(corpid, newParentChartCategoryList);
        }
    }



    /***
     * 获取需要插入分类数据的alias
     *
     * @param defaultList 默认分类列表
     * @param companyList 公司分类列表
     * @throws
     * @return List<String>
     * @author hongxiao
     * @date 2022-08-16 09:47
     * @since
     * @version
     */
    private List<String> getInsertAlias(List<ChartCategoryEntity> defaultList, List<ChartCategoryEntity> companyList) {
        if (CollectionsUtil.isEmpty(defaultList)) {
            return new ArrayList<>();
        }
        List<String> defaultAliasList = new ArrayList<>();
        defaultList.forEach(item -> defaultAliasList.add(item.getAlias()));
        List<String> companyAliasList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(companyList)) {
            companyList.forEach(item -> companyAliasList.add(item.getAlias()));
        }
        defaultAliasList.removeAll(companyAliasList);
        return defaultAliasList;
    }

    /***
     * 获取需要插入图表数据的systemCode
     *
     * @param defaultChartList 默认图表列表
     * @param systemChartList 公司图表列表
     * @throws
     * @return List<ChartEntity>
     * @author hongxiao
     * @date 2022-08-16 09:52
     * @since
     * @version
     */
    private List<ChartEntity> getInsertSystemCode(List<ChartEntity> defaultChartList, List<ChartEntity> systemChartList) {
        if (CollectionsUtil.isEmpty(defaultChartList)) {
            return null;
        }
        List<String> systemCodeList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(systemChartList)) {
            systemChartList.forEach(item -> systemCodeList.add(item.getSystemCode()));
        }
        List<ChartEntity> resultList = new ArrayList<>();
        for (ChartEntity chartEntity : defaultChartList) {
            if (systemCodeList.contains(chartEntity.getSystemCode())) {
                continue;
            }
            resultList.add(chartEntity);
        }
        return resultList;
    }

    /***
     * 获取默认分类与公司分类id对应map
     *
     * @param defaultList 默认分类列表
     * @param systemList 公司分类列表
     * @throws
     * @return java.util.Map<java.lang.Long,java.lang.Long>
     * @author hongxiao
     * @date 2022-08-16 09:53
     * @since
     * @version
     */
    private Map<Long, Long> getCategoryIdMap(List<ChartCategoryEntity> defaultList, List<ChartCategoryEntity> systemList) {
        Map<Long, Long> categoryIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //此处双层循环可优化
        for (ChartCategoryEntity oldEntity : defaultList) {
            for (ChartCategoryEntity newEntity : systemList) {
                //根据alias建立默认分类--系统分类的父IdMap
                if (Objects.equals(oldEntity.getAlias(), newEntity.getAlias())) {
                    categoryIdMap.put(oldEntity.getId(), newEntity.getId());
                    break;
                }
            }
        }
        return categoryIdMap;
    }



    /***
     * 插入新增子分类
     *
     * @param corpid 公司id
     * @param defaultChildChartCategoryList 默认子分类列表
     * @param insertAliasList 插入分类的alias
     * @param parentIdMap 父分类id对应map
     * @throws
     * @return void
     * @author hongxiao
     * @date 2022-08-16 09:56
     * @since
     * @version
     */
    private void insertChildChartCategory(String corpid, List<ChartCategoryEntity> defaultChildChartCategoryList, List<String> insertAliasList, Map<Long, Long> parentIdMap) {
        if (CollectionsUtil.isEmpty(defaultChildChartCategoryList)) {
            return;
        }
        if (CollectionsUtil.isEmpty(insertAliasList)) {
            return;
        }
        List<ChartCategoryEntity> insertList = new ArrayList<>();
        for (ChartCategoryEntity oldEntity : defaultChildChartCategoryList) {
            if (!insertAliasList.contains(oldEntity.getAlias())) {
                continue;
            }
            ChartCategoryEntity newEntity = new ChartCategoryEntity();
            BeanUtil.copyProperties(oldEntity, newEntity);
            newEntity.setCorpid(corpid);
            newEntity.setId(null);
            newEntity.setParentId(parentIdMap.get(newEntity.getParentId()));
            newEntity.setAddTime(DateTimeUtil.getInt());
            insertList.add(newEntity);
        }
        if (CollectionsUtil.isNotEmpty(insertList)) {
            chartCategoryModel.insertBatch(insertList);
        }
    }

    /***
     * 插入新增父分类
     *
     * @param corpid 公司corpid
     * @param defaultParentChartCategoryList 默认父分类列表
     * @param insertAliasList 插入分类的alias
     * @throws
     * @return void
     * @author hongxiao
     * @date 2022-08-16 09:58
     * @since
     * @version
     */
    private List<ChartCategoryEntity> insertParentChartCategory(String corpid, List<ChartCategoryEntity> defaultParentChartCategoryList, List<String> insertAliasList) throws XbbException {
        if (CollectionsUtil.isEmpty(defaultParentChartCategoryList)) {
            return null;
        }
        if (CollectionsUtil.isEmpty(insertAliasList)) {
            return null;
        }

        // 根据alias判断是否插入数据
        List<ChartCategoryEntity> insertList = new ArrayList<>();
        for (ChartCategoryEntity oldEntity : defaultParentChartCategoryList) {
            if (!insertAliasList.contains(oldEntity.getAlias())) {
                continue;
            }
            ChartCategoryEntity newEntity = new ChartCategoryEntity();
            BeanUtil.copyProperties(oldEntity, newEntity);
            newEntity.setId(null);
            newEntity.setCorpid(corpid);
            newEntity.setAddTime(DateTimeUtil.getInt());
            insertList.add(newEntity);
        }
        if (CollectionsUtil.isNotEmpty(insertList)) {
            chartCategoryModel.insertBatch(insertList);
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("columns", "version_id");
            param.put("corpid", corpid);
            MirrorCompanyEntity mirrorCompany = mirrorCompanyModel.getMirrorCompany(param);
            if (Objects.nonNull(mirrorCompany)) {
                updateSimpleIndexSet(corpid, insertList, mirrorCompany.getVersionId());
            } else {
                // 公司不使用镜像时按原逻辑
                updateIndexSet(corpid, insertList);
            }
        }
        return insertList;
    }

    /**
     * 父分类数量不相等，子分类数量不相等，插入新增父分类和子分类
     *
     * @param chartCategoryParentChildDTO 父子分类相关参数
     * @param chartCategoryInitDTO        获取corpid
     * @param chartCategoryMap            部分查询参数（typeIn，orderByStr）
     * @throws XbbException insertNewChildChartCategory会出现异常
     * @author 徐俊杰
     * @date 2019/1/29 20:00
     * @since v1.0
     */
    private void insertNewParentChildChartCategory(ChartCategoryParentChildDTO chartCategoryParentChildDTO, ChartCategoryInitDTO chartCategoryInitDTO, Map<String, Object> chartCategoryMap) throws XbbException {
        //给公司系统部分插入新的父分类
        insertNewParentChartCategory(chartCategoryParentChildDTO, chartCategoryInitDTO);
        //查询所有分类（插入父分类之后）
        chartCategoryMap.put("corpid", chartCategoryInitDTO.getCorpid());
        List<ChartCategoryEntity> newChartCategoryList = chartCategoryModel.findEntitys(chartCategoryMap);
        //拆分父子分类
        Map<String, List<ChartCategoryEntity>> chartCategoryListMap = separateParentChildList(newChartCategoryList);
        List<ChartCategoryEntity> systemParentChartCategoryList = chartCategoryListMap.get("parent");
        List<ChartCategoryEntity> systemChildChartCategoryList = chartCategoryListMap.get("child");
        Integer systemParentChartCategoryCount = systemParentChartCategoryList.size();
        Integer systemChildChartCategoryCount = systemChildChartCategoryList.size();
        //设置chartCategoryParentChildDTO
        chartCategoryParentChildDTO.setSystemParentChartCategoryList(systemParentChartCategoryList);
        chartCategoryParentChildDTO.setSystemChildChartCategoryList(systemChildChartCategoryList);
        chartCategoryParentChildDTO.setSystemParentChartCategoryCount(systemParentChartCategoryCount);
        chartCategoryParentChildDTO.setSystemChildChartCategoryCount(systemChildChartCategoryCount);
        //给公司系统部分插入新的子分类
        insertNewChildChartCategory(chartCategoryParentChildDTO, chartCategoryInitDTO);
    }

    /**
     * 获取默认--系统分类Id对应的map
     *
     * @param chartInitDTO 包含（corpid）
     * @return java.util.Map<java.lang.Long   ,   java.lang.Long>
     * @throws XbbException 父异常
     * @author 徐俊杰
     * @date 2019/2/1 8:57
     * @since v1.0
     */
    private Map<Long, Long> getOldNewCategoryIdMap(ChartInitDTO chartInitDTO) throws XbbException {
        Map<Long, Long> categoryIdMap = new HashMap<>(16);
        Map<String, Object> categoryMap = new HashMap<>(16);
        //获取系统分类
        List<Integer> typeIn = ChartCategoryTypeEnum.getCodeList4Init();
        categoryMap.put("corpid", chartInitDTO.getCorpid());
        categoryMap.put("typeIn", typeIn);
        categoryMap.put("orderByStr", "add_time DESC");
        categoryMap.put("columns", "id, alias");
        List<ChartCategoryEntity> systemCategoryList = chartCategoryModel.findEntitys(categoryMap);
        //获取默认分类
        categoryMap.put("corpid", "0");
        List<ChartCategoryEntity> defaultCategoryList = chartCategoryModel.findEntitys(categoryMap);
        return getCategoryIdMap(defaultCategoryList, systemCategoryList);
//        Integer systemCategoryCount = systemCategoryList.size();
//        Integer defaultCategoryCount = defaultCategoryList.size();
//        if (Objects.equals(systemCategoryCount, defaultCategoryCount)) {
//            for (ChartCategoryEntity oldEntity : defaultCategoryList) {
//                for (ChartCategoryEntity newEntity : systemCategoryList) {
//                    if (Objects.equals(oldEntity.getAlias(), newEntity.getAlias())) {
//                        categoryIdMap.put(oldEntity.getId(), newEntity.getId());
//                    }
//                }
//            }
//            return categoryIdMap;
//        } else {
//            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224017, String.format(StatisticsServicesErrorCodeEnum.API_ERROR_224017.getMsg(), I18nMessageUtil.getMessage(I18nStringConstant.CHART_CLASSIFY)));
//        }
    }

    /**
     * 更新IndexSet
     *
     * @param corpid 公司id
     * @param categoryList 图表分类列表
     * @throws XbbException updateBatch会出现异常
     * @author 徐俊杰
     * @date 2019/9/4 19:56
     * @since v1.0
     */
    private void updateIndexSet(String corpid, List<ChartCategoryEntity> categoryList) throws XbbException {
        //获取当前公司的默认indexSet
        Map<String, Object> indexSetParam = new HashMap<>();
        indexSetParam.put(StringConstant.CORPID, corpid);
        indexSetParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        indexSetParam.put("userId", "0");
        indexSetParam.put("del",0);
        List<IndexSetEntity> indexSetList = indexSetModel.findEntitys(indexSetParam);
        if (indexSetList.isEmpty()) {
            return;
        }
        //包装type-indexSet的Map
        Map<Integer, IndexSetEntity> typeIndexSetMap = new HashMap<>();
        for (IndexSetEntity indexSet : indexSetList) {
            Integer boardType = indexSet.getBoardType();
            typeIndexSetMap.put(boardType, indexSet);
        }
        List<IndexSetEntity> updateIndexSetList = new ArrayList<>();
        for (ChartCategoryEntity category : categoryList) {
            Integer type = category.getType();
            ChartCategoryTypeEnum typeEnum = ChartCategoryTypeEnum.getEnumByCode(type);
            Long categoryId = category.getId();
            switch (typeEnum) {
                case WEB_INDEX_LEFT:
                    //web左侧看板
                    IndexSetEntity indexSetWebLeft = typeIndexSetMap.get(BoardTypeEnum.WEB_LEFT.getCode());
                    addIndexSetData(indexSetWebLeft, categoryId);
                    updateIndexSetList.add(indexSetWebLeft);
                    //App看板
                    IndexSetEntity indexSetApp = typeIndexSetMap.get(BoardTypeEnum.DINGTALK.getCode());
                    addIndexSetData(indexSetApp, categoryId);
                    updateIndexSetList.add(indexSetApp);
                    break;
                case WEB_INDEX_RIGHT:
                    //web右侧看板
                    IndexSetEntity indexSetWebRight = typeIndexSetMap.get(BoardTypeEnum.WEB_RIGHT.getCode());
                    addIndexSetData(indexSetWebRight, categoryId);
                    updateIndexSetList.add(indexSetWebRight);
                    //App看板，移动端不需要添加的写方法过滤
                    indexSetApp = typeIndexSetMap.get(BoardTypeEnum.DINGTALK.getCode());
                    addIndexSetData(indexSetApp, categoryId);
                    updateIndexSetList.add(indexSetApp);
                    break;
                default:
                    break;
            }
        }
        //批量更新
        if (!CollectionsUtil.isEmpty(updateIndexSetList)) {
            indexSetModel.updateBatch(updateIndexSetList, corpid);
        }
    }

    /**
     * 将新加的图表分类加入indexSet
     *
     * @param indexSet 首页展示的分类与图表
     * @param categoryId 分类id
     * @author 徐俊杰
     * @date 2019/9/4 19:55
     * @since v1.0
     */
    private void addIndexSetData(IndexSetEntity indexSet, Long categoryId) {
        JSONArray contentData = indexSet.getContentData();
        List<IndexSetDataPojo> indexSetDataPojos = contentData.toJavaList(IndexSetDataPojo.class);
        //包装新加入的分类
        IndexSetDataPojo indexSetCategory = new IndexSetDataPojo();
        indexSetCategory.setEnable(1);
        indexSetCategory.setShowType(ChartTypeEnum.LINE_CHART.getCode());
        indexSetCategory.setEnableList(new ArrayList<>());
        indexSetCategory.setDisableList(new ArrayList<>());
        indexSetCategory.setChartCategoryId(categoryId);
        indexSetCategory.setChartCategoryType(ChartConstant.CHART_CATEGORY_TYPE_CATEGORY);
        //将首页已有的分类sort + 1
        for (IndexSetDataPojo pojo : indexSetDataPojos) {
            pojo.setSort(pojo.getSort() + BasicConstant.ONE);
        }
        //将新增的分类设置为尾部
        indexSetCategory.setSort(ChartConstant.TAIL_SORT);
        indexSetDataPojos.add(indexSetCategory);
        //进行排序
        indexSetDataPojos.sort((pojo1, pojo2) -> pojo2.getSort() - pojo1.getSort());
        contentData = JSONArray.parseArray(JSON.toJSONString(indexSetDataPojos));
        indexSet.setUpdateTime(DateTimeUtil.getInt());
        indexSet.setContentData(contentData);
    }

    /**
     * 更新indexSet图表相关数据
     *
     * @param corpid 公司id
     * @param chartList 图表列表
     * @throws XbbException updateBatch会出现异常
     * @author 徐俊杰
     * @date 2019/9/5 10:26
     * @since v1.0
     */
    private void updateIndexSetChart(String corpid, List<ChartEntity> chartList) throws XbbException {
        //循环图表列表，构造分类-图表列表映射
        Map<Long, List<ChartEntity>> categoryChartListMap = new HashMap<>(chartList.size());
        for (ChartEntity chart : chartList) {
            JSONArray categoryArray = chart.getCategory();
            if (categoryArray.size() == 1) {
                long category = categoryArray.getLongValue(0);
                List<ChartEntity> categoryChartList = categoryChartListMap.get(category);
                categoryChartList = categoryChartList == null ? new ArrayList<>() : categoryChartList;
                categoryChartList.add(chart);
                categoryChartListMap.put(category, categoryChartList);
            }
        }
        //获取当前公司的默认indexSet
        Map<String, Object> indexSetParam = new HashMap<>();
        indexSetParam.put(StringConstant.CORPID, corpid);
        indexSetParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        indexSetParam.put("userId", "0");
        indexSetParam.put("boardTypeIn", Arrays.asList(BoardTypeEnum.WEB_LEFT.getCode(), BoardTypeEnum.DINGTALK.getCode()));
        List<IndexSetEntity> indexSetList = indexSetModel.findEntitys(indexSetParam);
        if (indexSetList.isEmpty()) {
            return;
        }
        for (IndexSetEntity indexSet : indexSetList) {
            JSONArray contentData = indexSet.getContentData();
            List<IndexSetDataPojo> indexSetDataPojos = contentData.toJavaList(IndexSetDataPojo.class);
            for (IndexSetDataPojo data : indexSetDataPojos) {
                Integer type = data.getChartCategoryType();
                //取出里面的分类
                if (type == 1) {
                    Long categoryId = data.getChartCategoryId();
                    List<ChartEntity> categoryChartList = categoryChartListMap.get(categoryId);
                    if (categoryChartList != null) {
                        //处理enableList
                        List<IndexBoardChartSavePojo> enableList = data.getEnableList();
                        for (ChartEntity chart : categoryChartList) {
                            IndexBoardChartSavePojo chartSavePojo = new IndexBoardChartSavePojo();
                            chartSavePojo.setId(chart.getId());
                            chartSavePojo.setSort(chart.getSort());
                            chartSavePojo.setStatisticsType(StatisticsTypeEnum.SYSTEM_STATISTIC.getCode());
                            enableList.add(chartSavePojo);
                        }
                        //进行排序
                        enableList.sort((pojo1, pojo2) -> pojo2.getSort() - pojo1.getSort());
                    }
                }
            }
            contentData = JSONArray.parseArray(JSON.toJSONString(indexSetDataPojos));
            indexSet.setUpdateTime(DateTimeUtil.getInt());
            indexSet.setContentData(contentData);
        }
        //批量更新
        indexSetModel.updateBatch(indexSetList, corpid);
    }

    /**
     * CRM简易版-更新IndexSet
     *
     * @param corpid 公司id
     * @param categoryList 图表分类列表
     * @param versionId 镜像版本id
     * @throws XbbException updateBatch会出现异常
     * @author xingxing.xiao
     * @since v1.0
     */
    private void updateSimpleIndexSet(String corpid, List<ChartCategoryEntity> categoryList, Long versionId) throws XbbException {
        //获取当前公司的默认indexSet
        Map<String, Object> param = new HashMap<>();
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("userId", "0");
        List<IndexSetEntity> indexSetList = indexSetModel.findEntitys(param);
        if (indexSetList.isEmpty()) {
            return;
        }

        // 获取公司的图表镜像配置
        param.clear();
        param.put("versionId", versionId);
        param.put("module", MirrorModuleEnum.CATEGORY.getAlias());
        param.put("del", 0);
        MirrorInfoEntity mirrorModule = mirrorInfoModel.getMirrorModule(param);
        JSONObject jsonObject = JSONObject.parseObject(mirrorModule.getInfo());
        JSONArray centerArray = jsonObject.getJSONArray("centerList");
        JSONArray todoSeriesArray = jsonObject.getJSONArray("todoSeries");
        JSONArray categoryMirrorArray = new JSONArray();
        categoryMirrorArray.addAll(centerArray);
        categoryMirrorArray.addAll(todoSeriesArray);

        //包装type-indexSet的Map
        Map<Integer, IndexSetEntity> typeIndexSetMap = new HashMap<>();
        for (IndexSetEntity indexSet : indexSetList) {
            Integer boardType = indexSet.getBoardType();
            typeIndexSetMap.put(boardType, indexSet);
        }
        List<IndexSetEntity> updateIndexSetList = new ArrayList<>();
        for (ChartCategoryEntity category : categoryList) {
            Integer type = category.getType();
            ChartCategoryTypeEnum typeEnum = ChartCategoryTypeEnum.getEnumByCode(type);
            Long categoryId = category.getId();
            Integer enable = 1;
            if (!categoryMirrorArray.contains(category.getAlias())) {
                enable = 0;
            }
            switch (typeEnum) {
                case WEB_INDEX_LEFT:
                    //web左侧看板
                    IndexSetEntity indexSetWebLeft = typeIndexSetMap.get(BoardTypeEnum.WEB_LEFT.getCode());
                    addSimpleIndexSetData(indexSetWebLeft, categoryId, enable);
                    updateIndexSetList.add(indexSetWebLeft);
                    //App看板
                    IndexSetEntity indexSetApp = typeIndexSetMap.get(BoardTypeEnum.DINGTALK.getCode());
                    addSimpleIndexSetData(indexSetApp, categoryId, enable);
                    updateIndexSetList.add(indexSetApp);
                    break;
                case WEB_INDEX_RIGHT:
                    //web右侧看板
                    IndexSetEntity indexSetWebRight = typeIndexSetMap.get(BoardTypeEnum.WEB_RIGHT.getCode());
                    addSimpleIndexSetData(indexSetWebRight, categoryId, enable);
                    updateIndexSetList.add(indexSetWebRight);
                    if (Objects.equals(category.getAlias(),ChartCategoryAliasEnum.DATA_WARNING.getAlias())){
                        //App看板
                        indexSetApp = typeIndexSetMap.get(BoardTypeEnum.DINGTALK.getCode());
                        addIndexSetData(indexSetApp, categoryId);
                        updateIndexSetList.add(indexSetApp);
                    }
                    break;
                default:
                    break;
            }
        }
        //批量更新
        indexSetModel.updateBatch(updateIndexSetList, corpid);
    }

    /**
     * 将新加的图表分类加入indexSet
     *
     * @param indexSet 首页展示的分类与图表
     * @param categoryId 分类id
     * @param enable 开启关闭
     * @author xingxing.xiao
     */
    private void addSimpleIndexSetData(IndexSetEntity indexSet, Long categoryId, Integer enable) {
        JSONArray contentData = indexSet.getContentData();
        List<IndexSetDataPojo> indexSetDataPojos = contentData.toJavaList(IndexSetDataPojo.class);
        //包装新加入的分类
        IndexSetDataPojo indexSetCategory = new IndexSetDataPojo();
        indexSetCategory.setEnable(enable);
        indexSetCategory.setShowType(ChartTypeEnum.LINE_CHART.getCode());
        indexSetCategory.setEnableList(new ArrayList<>());
        indexSetCategory.setDisableList(new ArrayList<>());
        indexSetCategory.setChartCategoryId(categoryId);
        indexSetCategory.setChartCategoryType(ChartConstant.CHART_CATEGORY_TYPE_CATEGORY);
        //将首页已有的分类sort + 1
        for (IndexSetDataPojo pojo : indexSetDataPojos) {
            pojo.setSort(pojo.getSort() + BasicConstant.ONE);
        }
        //将新增的分类设置为尾部
        indexSetCategory.setSort(ChartConstant.TAIL_SORT);
        indexSetDataPojos.add(indexSetCategory);
        //进行排序
        indexSetDataPojos.sort((pojo1, pojo2) -> pojo2.getSort() - pojo1.getSort());
        contentData = JSONArray.parseArray(JSON.toJSONString(indexSetDataPojos));
        indexSet.setUpdateTime(DateTimeUtil.getInt());
        indexSet.setContentData(contentData);
    }

    /**
     * 更新indexSet图表相关数据
     *
     * @param corpid 公司id
     * @param chartList 图表列表
     * @param versionId 镜像版本id
     * @throws XbbException updateBatch会出现异常
     * @author xingxing.xiao
     */
    private void updateSimpleIndexSetChart(String corpid, List<ChartEntity> chartList, Long versionId) throws XbbException {
        //循环图表列表，构造分类-图表列表映射
        Map<Long, List<ChartEntity>> categoryChartListMap = new HashMap<>(chartList.size());
        for (ChartEntity chart : chartList) {
            JSONArray categoryArray = chart.getCategory();
            if (categoryArray.size() == 1) {
                long category = categoryArray.getLongValue(0);
                List<ChartEntity> categoryChartList = categoryChartListMap.get(category);
                categoryChartList = categoryChartList == null ? new ArrayList<>() : categoryChartList;
                categoryChartList.add(chart);
                categoryChartListMap.put(category, categoryChartList);
            }
        }
        //获取当前公司的默认indexSet
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("userId", "0");
        param.put("boardTypeIn", Arrays.asList(BoardTypeEnum.WEB_LEFT.getCode(), BoardTypeEnum.DINGTALK.getCode()));
        List<IndexSetEntity> indexSetList = indexSetModel.findEntitys(param);
        if (indexSetList.isEmpty()) {
            // 特殊：加一点逻辑，如果是第一次，更新下PK设置(因为在web端的“其他设置 -> pk榜设置”也可以设置选项)
            setPkEnable(corpid, chartList, versionId);
            return;
        }

        // 根据镜像配置关闭相应的类别
        param.clear();
        param.put("columns", "id, module, info");
        param.put("versionId", versionId);
        param.put("moduleIn", Arrays.asList(MirrorModuleEnum.CATEGORY.getAlias(), MirrorModuleEnum.CHART.getAlias()));
        param.put("del", 0);
        List<MirrorInfoEntity> infoList = mirrorInfoModel.findEntitys(param);
        JSONArray categoryArray = new JSONArray();
        JSONObject chartObj = new JSONObject();
        for (MirrorInfoEntity entity : infoList) {
            if (Objects.equals(entity.getModule(), MirrorModuleEnum.CATEGORY.getAlias())) {
                JSONObject categoryObj = JSONObject.parseObject(entity.getInfo());
                categoryArray.addAll(categoryObj.getJSONArray("centerList"));
                categoryArray.addAll(categoryObj.getJSONArray("todoSeries"));
            } else {
                // chart镜像配置
                chartObj = JSONObject.parseObject(entity.getInfo());
            }
        }

        // 提取所有chart镜像
        JSONArray chartArray = new JSONArray();
        for (Object obj : categoryArray) {
            JSONArray jsonArray = chartObj.getJSONArray(obj.toString());
            if (Objects.nonNull(jsonArray)) {
                chartArray.addAll(jsonArray);
            }
        }

        for (IndexSetEntity indexSet : indexSetList) {
            JSONArray contentData = indexSet.getContentData();
            List<IndexSetDataPojo> indexSetDataPojos = contentData.toJavaList(IndexSetDataPojo.class);
            for (IndexSetDataPojo data : indexSetDataPojos) {
                Integer type = data.getChartCategoryType();
                //取出里面的分类
                if (type == 1) {
                    Long categoryId = data.getChartCategoryId();
                    List<ChartEntity> categoryChartList = categoryChartListMap.get(categoryId);
                    if (categoryChartList != null) {
                        List<IndexBoardChartSavePojo> enableList = data.getEnableList();
                        List<IndexBoardChartSavePojo> disableList = data.getDisableList();
                        for (ChartEntity chart : categoryChartList) {
                            IndexBoardChartSavePojo chartSavePojo = new IndexBoardChartSavePojo();
                            chartSavePojo.setId(chart.getId());
                            chartSavePojo.setSort(chart.getSort());
                            chartSavePojo.setStatisticsType(StatisticsTypeEnum.SYSTEM_STATISTIC.getCode());
                            if (chartArray.contains(chart.getSystemCode())) {
                                enableList.add(chartSavePojo);
                            } else {
                                disableList.add(chartSavePojo);
                            }
                        }
                        //进行排序
                        enableList.sort((pojo1, pojo2) -> pojo2.getSort() - pojo1.getSort());
                        disableList.sort((pojo1, pojo2) -> pojo2.getSort() - pojo1.getSort());
                    }
                }
            }
            contentData = JSONArray.parseArray(JSON.toJSONString(indexSetDataPojos));
            indexSet.setUpdateTime(DateTimeUtil.getInt());
            indexSet.setContentData(contentData);
        }
        //批量更新
        indexSetModel.updateBatch(indexSetList, corpid);
    }

    /**
     * PK榜的特殊设置
     * @param corpid
     * @param chartList
     * @param versionId
     * @author xingxing.xiao
     * @date 2019/12/10 17:10
     */
    private void setPkEnable(String corpid, List<ChartEntity> chartList, Long versionId) {

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.clear();
        param.put("columns", "id, module, info");
        param.put("versionId", versionId);
        param.put("module", MirrorModuleEnum.CHART.getAlias());
        param.put("del", 0);
        MirrorInfoEntity mirrorModule = mirrorInfoModel.getMirrorModule(param);
        if (Objects.nonNull(mirrorModule)) {
            JSONObject jsonObject = JSONObject.parseObject(mirrorModule.getInfo());
            JSONArray pkArray = jsonObject.getJSONArray(ChartCategoryAliasEnum.PK.getAlias());
            param.clear();
            param.put("columns", "id, corpid, alias");
            param.put("corpid", corpid);
            param.put("alias", ChartCategoryAliasEnum.PK.getAlias());
            ChartCategoryEntity pkEntity = chartCategoryModel.getEntityByAlias(param);
            if (Objects.nonNull(pkEntity)) {
                Map<Long, List<ChartEntity>> pkListMap = new HashMap<>(chartList.size());
                for (ChartEntity chart : chartList) {
                    // pk 榜 size 为 2
                    JSONArray pkCategoryArray = chart.getCategory();
                    if (pkCategoryArray.size() == 2) {
                        long categoryId = pkCategoryArray.getLongValue(0);
                        List<ChartEntity> categoryChartList = pkListMap.get(categoryId);
                        categoryChartList = categoryChartList == null ? new ArrayList<>() : categoryChartList;
                        categoryChartList.add(chart);
                        pkListMap.put(categoryId, categoryChartList);
                    }
                }
                List<Long> chartIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<ChartEntity> chartEntities = pkListMap.get(pkEntity.getId());
                if (Objects.nonNull(chartEntities)) {
                    for (ChartEntity chartEntity : chartEntities) {
                        if (!pkArray.contains(chartEntity.getSystemCode()) && Objects.equals(chartEntity.getEnable(), BasicConstant.IS_USE)) {
                            chartIdIn.add(chartEntity.getId());
                        }
                    }
                    // 更新 chart 表中 pk 的开启关闭
                    param.clear();
                    param.put("corpid", corpid);
                    param.put("enable", BasicConstant.NO_USE);
                    param.put("idIn", chartIdIn);
                    chartModel.batchUpdateEnable(param);
                }
            }
        }
    }

    /**
     * 设置图表与数据集的对比时间
     *
     * @param editAble 是否编辑图表   true-编辑   false-新增
     * @param entityList 图表实体数组
     * @param now
     * @author zyy
     * @date 2022/10/11
     * @version v1.0
     */
    public void dataSetCompareTime(boolean editAble, List<ChartEntity> entityList, Long now) {
        if(CollectionsUtil.isEmpty(entityList)){
            return;
        }
        //新增图表时，数据源为数据集则直接设置对比时间
        if(!editAble){
            for (ChartEntity chartEntity : entityList) {
                 if(ChartSourceEnum.isDataSet(chartEntity.getSingle())){
                    chartEntity.setDataSetCompareTime(now);
                }
            }
            return;
        }
        //未返回则为编辑图表的操作
        entityList.forEach(newEntity -> {
            if(ChartSourceEnum.isDataSet(newEntity.getSingle())){
                newEntity.setDataSetCompareTime(now);
            }else{
                newEntity.setDataSetCompareTime(null);
            }
        });
    }
}
